<script setup lang="ts">
import { reactive, ref,onMounted } from "vue";

const next_time=ref('')

const get_next_time= async()=>{
  const url='/clock/next'
  const res= await fetch(url)
  if (res.ok==false) {
    alert("获取下次报时时间失败!\n"+res.statusText)
    return
  }
  const time_only=await res.json()
  const hour_str=time_only.hour>=10?time_only.hour:'0'+time_only.hour
  const minute_str=time_only.minute>=10?time_only.minute:'0'+time_only.minute
  next_time.value=hour_str+':'+minute_str
}



onMounted(async() => {
  await get_next_time()
  await refresh_settings()
})

const clock_settings=ref({})
const get_settings=async ()=>{
  const url='/clock/settings'
  const res= await fetch(url)
  if (res.ok==false) {
    alert('获取闹钟配置失败!\n'+res.statusText)
    return null
  }
  const settings= await res.json()
  console.log('获取配置:\n'+settings)
  return settings
}

const refresh_settings=async ()=>{
  const settings = await get_settings()
  if (settings) {
    clock_settings.value=reactive(settings)
  }
}

const validator_numbers=(value:string,min:number, max:number)=>{
  // console.log('validate:',value)
  // console.dir(value.trim().split(' '))
  const numbers=new Set()
  for (const item of value.trim().split(' ')) {
    const num=+item
    console.log(item)
    if (Number.isInteger(num)==false) {
      return new Error(`${item}不是一个整数!`)
    }
    if (num>max || num <min) {
      return new Error(`取值范围[${min},${max}], 而不是${num}`)
    }
    if (numbers.has(num)) {
      return new Error(`${num}已经存在!`)
    }
    numbers.add(num)
  }
  return null
}

const rules= {
  reportMinutes:{
    required:true,
    validator(rule,value:string){
      if (!value) {
        return new Error('需要报时分钟数!')
      }
      const res=validator_numbers(value,0,59)
      console.log(res)
      return !!res?res:true
    },
    trigger: ['input', 'blur']
  },
  silentHours:{
    // required:true,
    validator(rule,value:string){
      const res= validator_numbers(value,0,23)
      return !!res?res:true
    },
    trigger: ['input', 'blur']
  },
  enableBellRing:{
    required:true,
  },
  bellRepeatTime:{
    required:true,    
  },
  enableTimeReport:{
    required:true,
  }
}

const is_settings_changed=async ()=>{
  var new_json=JSON.stringify(clock_settings.value)
  var old_json=JSON.stringify(await get_settings())
  // console.log('old settings:',old_json);
  // console.log('new settings:',new_json);
  
  return new_json!=old_json
}

const is_loading=ref(false)
const submit_settings=async ()=>{
  is_loading.value=true
  if (await is_settings_changed()==false) {
    alert('配置没有变化, 无需上传!')
    is_loading.value=false
    return
  }
  const url='clock/settings'
  const res= await fetch(url,{
    method:'post',
    body:JSON.stringify(clock_settings.value),
    headers:{
      'Content-Type': 'application/json'
    }
  })
  if (res.ok) {
    alert('更新设置成功!')
    await refresh_settings()
  }else{
    alert('更新设置失败!\n'+res.statusText)
  }
  is_loading.value=false
}

const refresh_all=async ()=>{
  is_loading.value=true
  try {
    await get_next_time()
    await refresh_settings()
    
  } catch (error) {
    alert("刷新失败!\n"+error)
  }finally{    
    is_loading.value=false
  }
}

const test_time=reactive({
  hour:new Date().getHours(),
  minute:new Date().getMinutes(),
  force:true,
})
const test_rules={
  hour:{
    required:true,
  },
  minute:{
    required:true,
  }
}
const test_alarm=async()=>{
  is_loading.value=true
  const url=`/clock/test?hour=${test_time.hour}&minute=${test_time.minute}&force=${test_time.force}`
  try{

    const res=await fetch(url)
    if (res.ok==false) {
      alert('闹钟测试失败!\n'+res.statusText)
    }
  }finally{
    is_loading.value=false
  }
}
</script>

<template>
  <div class="clock-container">
    <div class="next-time-panel">
      <p class="panel-label">
      下次报时
      <n-button size="small" text @click="refresh_all()" :loading="is_loading">刷新</n-button>
      </p>
      <p class="panel-value">{{next_time}}</p>
    </div>
    <n-collapse  default-expanded-names="1" accordion>
      <n-collapse-item title="闹钟设置" name="1">
      <div class="setting-panel">
        <n-form
        :model="clock_settings"
        label-placement="left"
        label-width="140px"
        size="large"
        :rules="rules">
          <n-form-item label="报时时刻" path="reportMinutes" label-style="font-size:20px">
            <n-input
            v-model:value="clock_settings.reportMinutes" placeholder="输入以空格分隔的分钟" clearable 
            ></n-input>
          </n-form-item>
          <n-form-item label="静默时段" path="silentHours" label-style="font-size:20px">
            <n-input
            v-model:value="clock_settings.silentHours" placeholder="输入以空格分隔的小时" clearable 
            ></n-input>
          </n-form-item>
          <n-form-item label="启用钟声报时" path="enableBellRing" label-style="font-size:20px">
            <n-switch
            v-model:value="clock_settings.enableBellRing"
            ></n-switch>
          </n-form-item>
          <n-form-item label="钟声重复次数" path="bellRepeatTime" label-style="font-size:20px">
            <n-input-number
            v-model:value="clock_settings.bellRepeatTime" min="1"  :disabled="!clock_settings.enableBellRing"
            ></n-input-number>
          </n-form-item>
          <n-form-item label="启用语音报时" path="enableTimeReport" label-style="font-size:20px">
            <n-switch
            v-model:value="clock_settings.enableTimeReport"
            ></n-switch>
          </n-form-item>
          <div style="width:100%;display:flex;justify-content: center;">
            <n-button @click.prevent="submit_settings()" size="large" type="info" :loading="is_loading">上传
          </n-button>
          </div>
        </n-form>
      </div>
      </n-collapse-item>
      <n-collapse-item title="闹钟测试" name="2">
      <div class="test-panel">
        <n-form  
        label-placement="left"
        label-width="140px"
        size="large"
        :models="test_time"
        :rules="test_rules">
          <n-form-item label="测试小时数" label-style="font-size:20px" path="hour">
            <n-input-number v-model:value="test_time.hour" min="0" max="23"></n-input-number>
          </n-form-item>
          <n-form-item label="测试分钟数" label-style="font-size:20px" path="minute">
            <n-input-number v-model:value="test_time.minute" min="0" max="59"></n-input-number>
          </n-form-item>
          <n-form-item label="无视规则" label-style="font-size:20px" path="force">
            <n-switch v-model:value="test_time.force"></n-switch>
          </n-form-item>
          <div style="width:100%;display:flex;justify-content: center;">
            <n-button @click.prevent="test_alarm()" size="large" type="info" :loading="is_loading">测试
          </n-button>
          </div>
        </n-form>
      </div>
      </n-collapse-item>
    </n-collapse>
  </div>
</template>

<style scoped>
.clock-container {
  padding:20px 40px;
  background-color: rgba(255,255,255,.8);
  overflow: hidden;
  position: relative;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  font-family: "block";
  border-radius: 10px;
  width: 400px;
}
.transform-center {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  margin: 0;
}
.next-time-panel{
  font-size: 4vw;
  text-align: center;
}
.panel-label{
  margin: 0;
}
.panel-value{
  color: dodgerblue;
  margin: 0;
  font-size: 8vw;
  text-shadow: 2px 2px hsl(210, 100%, 80%);
}
.setting-panel{
  max-width: 600px;
  min-width: 400px;
  color: aliceblue;
  font-size: 20px;
}
</style>
